#ifndef DEVICE_CONTROL_H
#define DEVICE_CONTROL_H

#include <WiFi.h>
#include <HTTPClient.h>
#include <EEPROM.h>
#include <Ticker.h>
#include <ArduinoJson.h>
#include <AceButton.h>
#include <HTTPUpdate.h>
#include <FastDiode.h>
#include <Preferences.h>
#include <Ticker.h>

using namespace ace_button;

// ========================
// 数据类型声明 (Type Declarations)
// ========================
// 配置结构体，用于存储设备的网络配置信息
struct config_type
{
    char stassid[32]; // Wi-Fi SSID
    char stapsw[64];  // Wi-Fi 密码
    char cuid[40];    // 设备唯一标识符
    char ctopic[32];  // 主题名
    uint8_t reboot;   // 是否需要重启标志
    uint8_t magic;    // 魔法数字，用于验证配置的有效性
};

// ========================
// 宏定义 (Macros)
// ========================

#define TCP_SERVER_ADDR "bemfa.com" // 巴法云服务器地址，默认即可
#define TCP_SERVER_PORT "8344"      // 服务器端口，tcp创客云端口8344
#define MAX_PACKETSIZE 512          // 最大字节数
#define KEEPALIVEATIME 60 * 1000    // 设置心跳值30s

#define HOST_NAME "bemfa"
#define MAGIC_NUMBER 0xAA // 魔法数字，用于验证配置的有效性

#define MAX_LED_BRIGHTNESS 100 // LED最大亮度
#define DEFAULT_BRIGHTNESS 20  // 默认亮度

#define DEBOUNCE_DELAY 30    // 按键消抖延迟时间（毫秒）
#define LONG_PRESS_TIME 5000 // 长按判定时间为5000毫秒

// ========================
// 全局变量声明 (Global Variables)
// ========================

extern WiFiClient client_bemfa_WiFiClient; // 用于与巴法云服务器通信的客户端
extern HTTPClient http_bemfa_HTTPClient;   // HTTP客户端，用于HTTP请求
extern FastDiode LAMP;                     // LED控制对象
extern Ticker delayTimer;                  // 定时器对象，用于延时操作
extern AceButton ledButton;                // 按钮配置接口，用于处理按钮事件
// tcp客户端相关初始化，默认即可
extern WiFiClient TCPclient; // 用于TCP连接的客户端
extern config_type config;   // 配置结构体实例，存储设备的网络配置信息
extern WiFiUDP Udp;          // UDP客户端，用于UDP通信

//*****可以修改的地方******//
extern String aptype;  // 设备类型，例如插座、灯、风扇等
extern String Name;    // 设备昵称，可随意修改
extern String verSion; // 协议版本，3.1是tcp协议,1.1是mqtt协议
extern String room;    // 房间名称，例如客厅、卧室等，默认空
extern int adminID;    // 企业ID，建议企业用户配置，该设备会自动绑定到该企业下
extern int protoType;  // 协议类型，3是tcp设备端口8344,1是MQTT设备
extern int failCount;  // 定义失败连接次数
extern bool ledState;  // LED状态，true表示开，false表示关
extern String upUrl;   // OTA固件链接，请替换为自己的固件链接，如果接收到msg=update，开始执行固件升级
//**********************//
extern Preferences preferences; // 声明Preferences对象，用于存储亮度值信息
extern int savedBrightness;     // 保存的亮度值

extern bool firstWIfiConfig; // 检测是否是第一次连接Wi-Fi
extern String topic;         // 主题名
// tcp客户端相关初始化，默认即可
extern String TcpClient_Buff;            // TCP客户端缓冲区
extern unsigned int TcpClient_BuffIndex; // TCP客户端缓冲区索引
extern unsigned long TcpClient_preTick;  // 上一次TCP客户端tick时间
extern unsigned long preHeartTick;       // 上一次心跳包发送时间
extern unsigned long preTCPStartTick;    // 上一次TCP连接开始时间
extern bool preTCPConnected;             // 上一次TCP连接状态

extern int httpCode;           // HTTP响应代码
extern String UID;             // 用户ID
extern String TOPIC;           // 主题名（可能与上面的topic不同）
extern char config_flag;       // 配置标志
extern char packetBuffer[255]; // 发送数据包的缓冲区

extern unsigned long buttonPressTime;            // 按钮按下时间
extern unsigned long buttonReleaseTime;          // 按钮释放时间
extern const unsigned long LONG_PRESS_THRESHOLD; // 长按阈值（单位：毫秒）
extern bool isButtonPressed;                     // 按钮状态标志
// ========================
// 函数声明 (Function Declarations)
// ========================

// 更新固件相关函数
void update_started();                    // 更新固件开始
void update_finished();                   // 更新固件完成
void update_progress(int cur, int total); // 更新固件中
void update_error(int err);               // 更新固件错误
void updateBin();                         // 固件升级函数

// led 控制函数
void turnOnLed();                      // 打开LED
void turnOffLed();                     // 关闭LED
void setLedBrightness(int brightness); // 设置亮度
// 相关函数初始化
// 连接WIFI
void doWiFiTick();         // 执行Wi-Fi连接相关的tick操作
void startSTA();           // 启动Wi-Fi STA模式
void initWiFi();           // 初始化Wi-Fi设置
void waitKey();            // 检查是否需要airkiss配网
void checkFirstConfig();   // 检查是否是第一次配置
void apConfig(String mac); // AP配置，使用MAC地址

// TCP相关函数
void doTCPClientTick();         // 执行TCP客户端相关的tick操作
void startTCPClient();          // 启动TCP客户端
void sendtoTCPServer(String p); // 向TCP服务器发送数据

// EEPROM相关操作
void saveConfig(); // 保存配置到EEPROM
void loadConfig(); // 从EEPROM加载配置

// 其他函数
void IRAM_ATTR checkSwitch();                                    // 检查开关状态，使用中断处理
void delayRestart(float t);                                      // 延迟重启
void restoreFactory();                                           // 恢复出厂设置
void handleEvent(AceButton *button, uint8_t eventType, uint8_t); // 处理按钮事件

#endif // DEVICE_CONTROL_H